﻿#pragma once

#include "../Enums.h"
#include "../Data/ItemData.h"
#include <string>
#include <vector>
#include <cmath>
#include <any>
#include "../../stringhelper.h"

class Functions final
{
public:
    static bool CompareBytes(std::vector<unsigned char> &a, std::vector<unsigned char> &b);

    static std::string ConvertByteSize(double byteCount);

    static bool TryParse(const std::string &s, Point *&temp);
    static Point *Subtract(Point *p1, Point *p2);
    static Point *Subtract(Point *p1, int x, int y);
    static Point *Add(Point *p1, Point *p2);
    static Point *Add(Point *p1, int x, int y);
    static std::string PointToString(Point *p);
    static bool InRange(Point *a, Point *b, int i);

    static bool FacingEachOther(MirDirection dirA, Point *pointA, MirDirection dirB, Point *pointB);

    static std::string PrintTimeSpanFromSeconds(double secs, bool accurate = true);

    static std::string PrintTimeSpanFromMilliSeconds(double milliSeconds);

    static MirDirection PreviousDir(MirDirection d);
    static MirDirection NextDir(MirDirection d);
    static MirDirection DirectionFromPoint(Point *source, Point *dest);

    static MirDirection ShiftDirection(MirDirection dir, int i);

    static Size *Add(Size *p1, Size *p2);
    static Size *Add(Size *p1, int width, int height);

    static Point *PointMove(Point *p, MirDirection d, int i);
    static Point *Left(Point *p, MirDirection d);

    static Point *Right(Point *p, MirDirection d);

    static int MaxDistance(Point *p1, Point *p2);

    static MirDirection ReverseDirection(MirDirection dir);
    static ItemInfo *GetRealItem(ItemInfo *Origin, unsigned short Level, MirClass job, std::vector<ItemInfo*> &ItemList);
    static ItemInfo *GetLevelBasedItem(ItemInfo *Origin, unsigned short level, std::vector<ItemInfo*> &ItemList);
    static ItemInfo *GetClassBasedItem(ItemInfo *Origin, MirClass job, std::vector<ItemInfo*> &ItemList);

    static ItemInfo *GetClassAndLevelBasedItem(ItemInfo *Origin, MirClass job, unsigned short level, std::vector<ItemInfo*> &ItemList);

    static std::string StringOverLines(const std::string &line, int maxWordsPerLine, int maxLettersPerLine);

    static std::vector<std::vector<unsigned char>> SplitArray(std::vector<unsigned char> &value, int bufferLength);

    static std::vector<unsigned char> CombineArray(std::vector<std::vector<unsigned char>> &arrays);
    template<typename T>
    static std::vector<unsigned char> SerializeToBytes(T item)
    {
        auto formatter = new BinaryFormatter();
//C# TO C++ CONVERTER NOTE: The following 'using' block is replaced by its C++ equivalent:
//ORIGINAL LINE: using (var stream = new MemoryStream())
        {
            auto stream = MemoryStream();
            formatter->Serialize(stream, item);
            stream.Seek(0, SeekOrigin::Begin);

            delete formatter;
            return stream.ToArray();
        }

        delete formatter;
    }
    static std::any DeserializeFromBytes(std::vector<unsigned char> &bytes);
};
